package com.virxue.baseweb.utils;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.commons.collections.MapUtils;
import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpDelete;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.alibaba.fastjson.JSONObject;
import com.virxue.baseweb.exception.ServiceRuntimeException;

/**
 * @ClassName HttpClientUtil
 * @Description http请求工具类
 *
 * @author sunhaojie 3113751575@qq.com
 * @date 2016年8月22日 下午2:40:56
 */
public class JsonHttpClientUtil {
    private static final Logger logger = LoggerFactory.getLogger(JsonHttpClientUtil.class);

    private static CloseableHttpClient httpclient = HttpClients.createDefault();
    private final static String charset = "UTF-8";

    public static String delete(String url, Map<String, String> headerMap, Map<String, String> paramMap, String charset) {
        //处理入参
        String newUrl = url;
        if (MapUtils.isNotEmpty(paramMap)) {
            List<NameValuePair> pairs = new ArrayList<NameValuePair>(paramMap.size());
            for (String name : paramMap.keySet()) {
                pairs.add(new BasicNameValuePair(name, paramMap.get(name)));
            }

            String paramString = null;
            try {
                String curRequestCharset = JsonHttpClientUtil.charset;
                if (charset != null) {
                    curRequestCharset = charset;
                }
                paramString = EntityUtils.toString(new UrlEncodedFormEntity(pairs, curRequestCharset));
            } catch (Exception e) {
                logger.error("编码错误", e);
                throw new ServiceRuntimeException("HTTP_CLIENT_ENCODING_ERROR", e);
            }

            if (url.indexOf("?") > -1) {
                newUrl = url + "&" + paramString;
            } else {
                newUrl = url + "?" + paramString;
            }
        }

        //处理地址
        HttpDelete httpDelete = new HttpDelete(newUrl);

        //处理head
        if (MapUtils.isNotEmpty(headerMap)) {
            for (String name : headerMap.keySet()) {
                httpDelete.addHeader(name, headerMap.get(name));
            }
        }

        return execute(httpDelete);
    }

    /**
     * 
     * @Title put
     * @Description put提交
     * @param url
     * @param headerMap
     * @param paramMap
     * @param charset
     * @return
     *
     * @author sunhaojie 3113751575@qq.com
     * @date 2016年8月25日 下午6:17:25
     */
    public static String put(String url, Map<String, String> headerMap, Map<String, String> paramMap, String charset) {
        //初始化对象
        HttpPut httpPut = new HttpPut(url);

        //处理heard
        if (MapUtils.isNotEmpty(headerMap)) {
            for (String key : headerMap.keySet()) {
                httpPut.addHeader(key, headerMap.get(key));
            }
        }

        //处理入参
        if (MapUtils.isNotEmpty(paramMap)) {
            ContentType contentType = null;
            if (charset != null) {
                contentType = ContentType.create("application/json", charset);
            } else {
                contentType = ContentType.create("application/json", JsonHttpClientUtil.charset);
            }
            HttpEntity entity = new StringEntity(JSONObject.toJSONString(paramMap), contentType);
            httpPut.setEntity(entity);
        }

        return execute(httpPut);
    }

    /**
     * 
     * @Title post
     * @Description post提交
     * @param url
     * @param headerMap
     * @param paramMap
     * @param charset
     * @return
     *
     * @author sunhaojie 3113751575@qq.com
     * @date 2016年8月25日 下午6:13:56
     */
    public static String post(String url, Map<String, String> headerMap, Map<String, String> paramMap, String charset) {
        //初始化对象
        HttpPost httpPost = new HttpPost(url);

        //处理heard
        if (MapUtils.isNotEmpty(headerMap)) {
            for (String key : headerMap.keySet()) {
                httpPost.addHeader(key, headerMap.get(key));
            }
        }

        //处理入参
        if (MapUtils.isNotEmpty(paramMap)) {
            ContentType contentType = null;
            if (charset != null) {
                contentType = ContentType.create("application/json", charset);
            } else {
                contentType = ContentType.create("application/json", JsonHttpClientUtil.charset);
            }
            HttpEntity entity = new StringEntity(JSONObject.toJSONString(paramMap), contentType);
            httpPost.setEntity(entity);
        }

        return execute(httpPost);
    }

    /**
     * 
     * @Title get
     * @Description get方式调用rest请求，get方式入参不使用json格式
     * @param url
     * @param headerMap
     * @param paramMap
     * @param charset
     * @return
     *
     * @author sunhaojie 3113751575@qq.com
     * @date 2016年8月25日 下午5:45:21
     */
    public static String get(String url, Map<String, String> headerMap, Map<String, String> paramMap, String charset) {

        //处理入参
        String newUrl = url;
        if (MapUtils.isNotEmpty(paramMap)) {
            List<NameValuePair> pairs = new ArrayList<NameValuePair>(paramMap.size());
            for (String name : paramMap.keySet()) {
                pairs.add(new BasicNameValuePair(name, paramMap.get(name)));
            }

            String paramString = null;
            try {
                String curRequestCharset = JsonHttpClientUtil.charset;
                if (charset != null) {
                    curRequestCharset = charset;
                }
                paramString = EntityUtils.toString(new UrlEncodedFormEntity(pairs, curRequestCharset));
            } catch (Exception e) {
                logger.error("编码错误", e);
                throw new ServiceRuntimeException("HTTP_CLIENT_ENCODING_ERROR", e);
            }

            if (url.indexOf("?") > -1) {
                newUrl = url + "&" + paramString;
            } else {
                newUrl = url + "?" + paramString;
            }
        }

        //处理地址
        HttpGet httpget = new HttpGet(newUrl);

        //处理head
        if (MapUtils.isNotEmpty(headerMap)) {
            for (String name : headerMap.keySet()) {
                httpget.addHeader(name, headerMap.get(name));
            }
        }

        return execute(httpget);
    }

    /**
     * 
     * @Title execute
     * @Description 执行调用
     * @param request
     * @return
     *
     * @author sunhaojie 3113751575@qq.com
     * @date 2016年8月22日 下午3:17:00
     */
    private static String execute(HttpUriRequest request) {
        CloseableHttpResponse response = null;

        try {
            response = httpclient.execute(request);
        } catch (IOException e) {
            logger.error("调用接口异常", e);
            throw new ServiceRuntimeException("HTTP_CLIENT_IO_ERROR", e);
        }

        if (response == null) {
            logger.error("response为null");
            throw new ServiceRuntimeException("HTTP_CLIENT_NO_RESPONSE_ERROR");
        }

        if (response.getStatusLine().getStatusCode() != 200) {
            throw new ServiceRuntimeException("HTTP_CLIENT_STATUS_ERROR");
        }

        HttpEntity httpEntity = response.getEntity();
        StringBuffer resultStringBuffer = new StringBuffer();

        try {
            InputStream inputStream = httpEntity.getContent();
            String curRequestCharset = charset;
            if (httpEntity.getContentEncoding() != null) {
                curRequestCharset = httpEntity.getContentEncoding().getValue();
            }
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream, curRequestCharset));
            String line = bufferedReader.readLine();
            while (line != null) {
                resultStringBuffer.append(line);
                line = bufferedReader.readLine();
            }

        } catch (IllegalStateException e) {
            logger.error("调用接口异常", e);
            e.printStackTrace();
            throw new ServiceRuntimeException("HTTP_CLIENT_ILLEGAL_STATE_ERROR", e);
        } catch (IOException e) {
            logger.error("调用接口异常", e);
            e.printStackTrace();
            throw new ServiceRuntimeException("HTTP_CLIENT_IO_ERROR", e);
        } catch (Exception e) {
            logger.error("调用接口异常", e);
            e.printStackTrace();
            throw new ServiceRuntimeException("HTTP_CLIENT_ERROR", e);
        }

        return resultStringBuffer.toString();
    }

    public static void main(String[] args) {
        Map<String, String> paramMap = new HashMap<String, String>();
        paramMap.put("status", 200 + "");
        paramMap.put("errorCode", "test");
        paramMap.put("message", "中文测试111");
        String result = JsonHttpClientUtil.delete("http://127.0.0.1:8080/http_client", null, paramMap, "UTF-8");
        System.out.println(result);
    }
}